#ifndef ZUC_NML_HH
#define ZUC_NML_HH
#include "nml_intf/zuc.hh"
#include "rcs.hh"
#include "cmd_msg.hh"
#include "stat_msg.hh"
#include "nml_intf/zuc_nml_axis.hh"
#include "nml_intf/zuc_nml_io_commu.hh"
#include "nml_intf/zuc_nml_rob.hh"
#include "nml_intf/zuc_nml_rob_cmd.hh"
#include "nml_intf/zuc_nml_safe.hh"
#include "nml_intf/interpl.hh"

#include "zuc/nml_intf/zucpos.h"
#include "zuc/nml_intf/zucpos2.h"
#include "nml_intf/canon.hh"     // CANON_TOOL_TABLE, CANON_UNITS
#include "rs274ngc/rs274ngc.hh"  // ACTIVE_G_CODES, etc
#include "motion/safezone.h"
#include "rtdev/tio_intf_c.h"

#define JOGTELEOP 0
#define JOGJOINT 1
#define JOGTELEOP_TOOL 2
#define MAX_CALIB_STRUCY_POS_CNT 24

// ------------------
// CLASS DECLARATIONS
// ------------------

// declarations for ZUC general classes

/**
 * Send a textual error message to the operator.
 * The message is put in the errlog buffer to be read by the GUI.
 * This allows the controller a generic way to send error messages to
 * the operator.
 */
class ZUC_OPERATOR_ERROR : public RCS_CMD_MSG
{
public:
    ZUC_OPERATOR_ERROR() : RCS_CMD_MSG(ZUC_OPERATOR_ERROR_TYPE, sizeof(ZUC_OPERATOR_ERROR)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int id;
    int errcode;
    char error[LINELEN];
};

/**
 * Send a textual information message to the operator.
 * This is similiar to ZUC_OPERATOR_ERROR message except that the messages are
 * sent in situations not necessarily considered to be errors.
 */
class ZUC_OPERATOR_TEXT : public RCS_CMD_MSG
{
public:
    ZUC_OPERATOR_TEXT() : RCS_CMD_MSG(ZUC_OPERATOR_TEXT_TYPE, sizeof(ZUC_OPERATOR_TEXT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int id;
    char text[LINELEN];
};

/**
 * Send the URL or filename of a document to display.
 * This message is placed in the errlog buffer  to be read by the GUI.
 * If the GUI is capable of doing so it will show the operator a
 * previously created document, using the URL or filename provided.
 * This message is placed in the errlog channel to be read by the GUI.
 * This provides a general means of reporting an error from within the
 * controller without having to program the GUI to recognize each error type.
 */
class ZUC_OPERATOR_DISPLAY : public RCS_CMD_MSG
{
public:
    ZUC_OPERATOR_DISPLAY() : RCS_CMD_MSG(ZUC_OPERATOR_DISPLAY_TYPE, sizeof(ZUC_OPERATOR_DISPLAY)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int id;
    char display[LINELEN];
};

#define ZUC_SYSTEM_CMD_LEN 256
/*
 execute a system command
 */
class ZUC_SYSTEM_CMD : public RCS_CMD_MSG
{
public:
    ZUC_SYSTEM_CMD() : RCS_CMD_MSG(ZUC_SYSTEM_CMD_TYPE, sizeof(ZUC_SYSTEM_CMD)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    char string[ZUC_SYSTEM_CMD_LEN];
};

class ZUC_NULL : public RCS_CMD_MSG
{
public:
    ZUC_NULL() : RCS_CMD_MSG(ZUC_NULL_TYPE, sizeof(ZUC_NULL)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_SET_DEBUG : public RCS_CMD_MSG
{
public:
    ZUC_SET_DEBUG() : RCS_CMD_MSG(ZUC_SET_DEBUG_TYPE, sizeof(ZUC_SET_DEBUG)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int debug;
};

class ZUC_SET_CABVOLTAGE : public RCS_CMD_MSG
{
public:
    ZUC_SET_CABVOLTAGE() : RCS_CMD_MSG(ZUC_SET_CABVOLTAGE_TYPE, sizeof(ZUC_SET_CABVOLTAGE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int cabVoltage;
};

class ZUC_APP_SET_CONNECTSTAT : public RCS_CMD_MSG
{
public:
    ZUC_APP_SET_CONNECTSTAT() : RCS_CMD_MSG(ZUC_APP_SET_CONNECTSTAT_TYPE, sizeof(ZUC_APP_SET_CONNECTSTAT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int status;
};

class ZUC_SETUP_MODBUS_SLAVE : public RCS_CMD_MSG
{
public:
    ZUC_SETUP_MODBUS_SLAVE() : RCS_CMD_MSG(ZUC_SETUP_MODBUS_SLAVE_TYPE, sizeof(ZUC_SETUP_MODBUS_SLAVE)){};

    void update(CMS* cms);
    int commType;
    CommInfo mbComm;
};
//
class ZUC_EXTIO_SETUP : public RCS_CMD_MSG
{
public:
    ZUC_EXTIO_SETUP() : RCS_CMD_MSG(ZUC_EXTIO_SETUP_TYPE, sizeof(ZUC_EXTIO_SETUP)){};

    void update(CMS* cms);
    int extIOModCnt;
    ExtIOSetup extIOSetup[MAX_EXTIO_CNT];  ///< setup from client
};

class ZUC_EXTIO_SETMODE : public RCS_CMD_MSG
{
public:
    ZUC_EXTIO_SETMODE() : RCS_CMD_MSG(ZUC_EXTIO_SETMODE_TYPE, sizeof(ZUC_EXTIO_SETMODE)){};

    void update(CMS* cms);
    int mode;  // 0->maintenance mode; 1->operation mode
};

class ZUC_SET_MAINTENANCE_MODE : public RCS_CMD_MSG
{
public:
    ZUC_SET_MAINTENANCE_MODE() : RCS_CMD_MSG(ZUC_SET_MAINTENANCE_MODE_TYPE, sizeof(ZUC_SET_MAINTENANCE_MODE)){};

    void update(CMS* cms);
    int maintenance;  // 进入维护状态 1 退出维护状态 0
};

class ZUC_TORQSENSOR_SETCOMM : public RCS_CMD_MSG
{
public:
    ZUC_TORQSENSOR_SETCOMM() : RCS_CMD_MSG(ZUC_TORQSENSOR_SETCOMM_TYPE, sizeof(ZUC_TORQSENSOR_SETCOMM)) {}

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int commType;  // 0 for tcp/ip, 1 for tool modbus rtu
    CommInfo commCfg;
};

class ZUC_TORQSENSOR_SETPAYLOAD : public RCS_CMD_MSG
{
public:
    ZUC_TORQSENSOR_SETPAYLOAD() : RCS_CMD_MSG(ZUC_TORQSENSOR_SETPAYLOAD_TYPE, sizeof(ZUC_TORQSENSOR_SETPAYLOAD)) {}

    // For internal NML/CMS use only.
    void update(CMS* cms);
    Payload payload;
};

class ZUC_TOOL_SETPAYLOAD : public RCS_CMD_MSG
{
public:
    ZUC_TOOL_SETPAYLOAD() : RCS_CMD_MSG(ZUC_TOOL_SETPAYLOAD_TYPE, sizeof(ZUC_TOOL_SETPAYLOAD)) {}

    // For internal NML/CMS use only.
    void update(CMS* cms);
    Payload payload;
};

class ZUC_FUNCTION_SAFTY_PARA : public RCS_CMD_MSG
{
public:
    ZUC_FUNCTION_SAFTY_PARA() : RCS_CMD_MSG(ZUC_FUNCTION_SAFTY_PARA_TYPE, sizeof(ZUC_FUNCTION_SAFTY_PARA)) {}

    void update(CMS* cms);

    double robot_power_limit[2];
    double robot_momentum_limit[2];
    double robot_endforce_limit[2];
    double robot_velocity_limit;
};

class ZUC_IDENTIFY_CYCLE_TIME : public RCS_CMD_MSG
{
public:
    ZUC_IDENTIFY_CYCLE_TIME() : RCS_CMD_MSG(ZUC_IDENTIFY_CYCLE_TIME_TYPE, sizeof(ZUC_IDENTIFY_CYCLE_TIME)) {}

    void update(CMS* cms);

    int identify_cycle_time;
};

class ZUC_COLLISION_GM_RECORD_ENABLE : public RCS_CMD_MSG
{
public:
    ZUC_COLLISION_GM_RECORD_ENABLE() : RCS_CMD_MSG(ZUC_COLLISION_GM_RECORD_ENABLE_TYPE, sizeof(ZUC_COLLISION_GM_RECORD_ENABLE)) {}

    void update(CMS* cms);

    int gm_record_enable;
};

class ZUC_SET_ROBOT_NAME : public RCS_CMD_MSG
{
public:
    ZUC_SET_ROBOT_NAME() : RCS_CMD_MSG(ZUC_SET_ROBOT_NAME_TYPE, sizeof(ZUC_SET_ROBOT_NAME)){};

    char name[LINELEN];
    void update(CMS* cms);
};

class ZUC_SET_CABINET_ID : public RCS_CMD_MSG
{
public:
    ZUC_SET_CABINET_ID() : RCS_CMD_MSG(ZUC_SET_CABINET_ID_TYPE, sizeof(ZUC_SET_CABINET_ID)){};

    int cabinet_id;
    void update(CMS* cms);
};

class ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_STARTPOS : public RCS_CMD_MSG
{
public:
    ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_STARTPOS()
        : RCS_CMD_MSG(ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_STARTPOS_TYPE, sizeof(ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_STARTPOS)){};

    int trajId;
    JointTraj jointTraj;
    void update(CMS* cms);
};

class ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_ENDPOS : public RCS_CMD_MSG
{
public:
    ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_ENDPOS()
        : RCS_CMD_MSG(ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_ENDPOS_TYPE, sizeof(ZUC_TASK_SET_PAYLOAD_IDENTIFY_TRAJ_ENDPOS)){};

    int trajId;
    JointTraj jointTraj;
    void update(CMS* cms);
};

class ZUC_TASK_START_PAYLOAD_IDENTIFY_TRAJ : public RCS_CMD_MSG
{
public:
    ZUC_TASK_START_PAYLOAD_IDENTIFY_TRAJ() : RCS_CMD_MSG(ZUC_TASK_START_PAYLOAD_IDENTIFY_TRAJ_TYPE, sizeof(ZUC_TASK_START_PAYLOAD_IDENTIFY_TRAJ)){};

    int trajId;
    int withPayload;
    void update(CMS* cms);
};

class ZUC_TASK_RESET_PAYLOAD_IDENTIFY_STATUS : public RCS_CMD_MSG
{
public:
    ZUC_TASK_RESET_PAYLOAD_IDENTIFY_STATUS() : RCS_CMD_MSG(ZUC_TASK_RESET_PAYLOAD_IDENTIFY_STATUS_TYPE, sizeof(ZUC_TASK_RESET_PAYLOAD_IDENTIFY_STATUS)){};

    int userOpt;  // 0: both, 1:only with payload, 2: only without load
    void update(CMS* cms);
};

class ZUC_GET_PAYLOAD_IDENTIFY_RESULT : public RCS_CMD_MSG
{
public:
    ZUC_GET_PAYLOAD_IDENTIFY_RESULT() : RCS_CMD_MSG(ZUC_GET_PAYLOAD_IDENTIFY_RESULT_TYPE, sizeof(ZUC_GET_PAYLOAD_IDENTIFY_RESULT)){};

    int heartBeat;
    void update(CMS* cms);
};

class ZUC_STOP_IDENTIFY_FRICTION : public RCS_CMD_MSG
{
public:
    ZUC_STOP_IDENTIFY_FRICTION() : RCS_CMD_MSG(ZUC_STOP_IDENTIFY_FRICTION_TYPE, sizeof(ZUC_STOP_IDENTIFY_FRICTION)) {}

    void update(CMS* cms);

    int friction_identify_joint_index;
};

class ZUC_START_IDENTIFY_FRICTION : public RCS_CMD_MSG
{
public:
    ZUC_START_IDENTIFY_FRICTION() : RCS_CMD_MSG(ZUC_START_IDENTIFY_FRICTION_TYPE, sizeof(ZUC_START_IDENTIFY_FRICTION)) {}

    void update(CMS* cms);

    int friction_identify_joint_index;
};

class ZUC_SYNC_ZUCSETTINGS : public RCS_CMD_MSG
{
public:
    ZUC_SYNC_ZUCSETTINGS() : RCS_CMD_MSG(ZUC_SYNC_ZUCSETTINGS_TYPE, sizeof(ZUC_SYNC_ZUCSETTINGS)){};

    void update(CMS* cms);
};

class ZUC_IDENTIFY_FRICTION_END_POS : public RCS_CMD_MSG
{
public:
    ZUC_IDENTIFY_FRICTION_END_POS() : RCS_CMD_MSG(ZUC_IDENTIFY_FRICTION_END_POS_TYPE, sizeof(ZUC_IDENTIFY_FRICTION_END_POS)) {}

    void update(CMS* cms);

    int friction_identify_joint_index;
    double friction_identify_end_pos[ZUCMOT_MAX_JOINTS];
};

class ZUC_IDENTIFY_FRICTION_START_POS : public RCS_CMD_MSG
{
public:
    ZUC_IDENTIFY_FRICTION_START_POS() : RCS_CMD_MSG(ZUC_IDENTIFY_FRICTION_START_POS_TYPE, sizeof(ZUC_IDENTIFY_FRICTION_START_POS)) {}

    void update(CMS* cms);

    int friction_identify_joint_index;
    double friction_identify_start_pos[ZUCMOT_MAX_JOINTS];
};

class ZUC_RS485_MESSAGE : public RCS_CMD_MSG
{
public:
    ZUC_RS485_MESSAGE() : RCS_CMD_MSG(ZUC_RS485_MESSAGE_TYPE, sizeof(ZUC_RS485_MESSAGE)) {}

    void update(CMS* cms);

    int chn;
    int len;
};

class ZUC_TIO_RS485_SIG_PROG_STAT : public RCS_CMD_MSG
{
public:
    ZUC_TIO_RS485_SIG_PROG_STAT() : RCS_CMD_MSG(ZUC_TIO_RS485_SIG_PROG_STAT_TYPE, sizeof(ZUC_TIO_RS485_SIG_PROG_STAT)) {}

    void update(CMS* cms);

    char sig_name[128];
    int prog_stat;
};

class ZUC_TORQUE_CONTROL_ENABLE : public RCS_CMD_MSG
{
public:
    ZUC_TORQUE_CONTROL_ENABLE() : RCS_CMD_MSG(ZUC_TORQUE_CONTROL_ENABLE_TYPE, sizeof(ZUC_TORQUE_CONTROL_ENABLE)) {}

    void update(CMS* cms);

    int torque_control_enable;
    int torque_last_period;
};

class ZUC_GRAVITY_DIRECTION : public RCS_CMD_MSG
{
public:
    ZUC_GRAVITY_DIRECTION() : RCS_CMD_MSG(ZUC_GRAVITY_DIRECTION_TYPE, sizeof(ZUC_GRAVITY_DIRECTION)) {}

    void update(CMS* cms);

    double rpy[3];
};

class ZUC_DRAG_CONTROL_ENABLE : public RCS_CMD_MSG
{
public:
    ZUC_DRAG_CONTROL_ENABLE() : RCS_CMD_MSG(ZUC_DRAG_CONTROL_ENABLE_TYPE, sizeof(ZUC_DRAG_CONTROL_ENABLE)) {}

    void update(CMS* cms);

    int drag_control_enable;
};

class ZUC_DRAG_CONTROL_FC_COMPENSATE : public RCS_CMD_MSG
{
public:
    ZUC_DRAG_CONTROL_FC_COMPENSATE() : RCS_CMD_MSG(ZUC_DRAG_CONTROL_FC_COMPENSATE_TYPE, sizeof(ZUC_DRAG_CONTROL_FC_COMPENSATE)) {}

    void update(CMS* cms);

    int drag_control_fc_compensate[ZUCMOT_MAX_JOINTS];
};

class ZUC_DRAG_CONTROL_FV_COMPENSATE : public RCS_CMD_MSG
{
public:
    ZUC_DRAG_CONTROL_FV_COMPENSATE() : RCS_CMD_MSG(ZUC_DRAG_CONTROL_FV_COMPENSATE_TYPE, sizeof(ZUC_DRAG_CONTROL_FV_COMPENSATE)) {}

    void update(CMS* cms);

    int drag_control_fv_compensate[ZUCMOT_MAX_JOINTS];
};

class ZUC_DRAG_CONTROL_FILTER_FACTOR : public RCS_CMD_MSG
{
public:
    ZUC_DRAG_CONTROL_FILTER_FACTOR() : RCS_CMD_MSG(ZUC_DRAG_CONTROL_FILTER_FACTOR_TYPE, sizeof(ZUC_DRAG_CONTROL_FILTER_FACTOR)) {}

    void update(CMS* cms);

    int drag_control_filter_factor[ZUCMOT_MAX_JOINTS];
};

class ZUC_DRAG_CONTROL_DITHER_FACTOR : public RCS_CMD_MSG
{
public:
    ZUC_DRAG_CONTROL_DITHER_FACTOR() : RCS_CMD_MSG(ZUC_DRAG_CONTROL_DITHER_FACTOR_TYPE, sizeof(ZUC_DRAG_CONTROL_DITHER_FACTOR)) {}

    void update(CMS* cms);

    double drag_control_dither_factor[ZUCMOT_MAX_JOINTS];
};

class ZUC_TASK_START_DYNAMICS_IDENTIFY : public RCS_CMD_MSG
{
public:
    ZUC_TASK_START_DYNAMICS_IDENTIFY() : RCS_CMD_MSG(ZUC_TASK_START_DYNAMICS_IDENTIFY_TYPE, sizeof(ZUC_TASK_START_DYNAMICS_IDENTIFY)){};

    int heartBeat;
    void update(CMS* cms);
};

class ZUC_TASK_STOP_DYNAMICS_IDENTIFY : public RCS_CMD_MSG
{
public:
    ZUC_TASK_STOP_DYNAMICS_IDENTIFY() : RCS_CMD_MSG(ZUC_TASK_STOP_DYNAMICS_IDENTIFY_TYPE, sizeof(ZUC_TASK_STOP_DYNAMICS_IDENTIFY)){};

    int heartBeat;
    void update(CMS* cms);
};

class ZUC_SET_NET_EXCEPTION_HANDLE : public RCS_CMD_MSG
{
public:
    ZUC_SET_NET_EXCEPTION_HANDLE() : RCS_CMD_MSG(ZUC_SET_NET_EXCEPTION_HANDLE_TYPE, sizeof(ZUC_SET_NET_EXCEPTION_HANDLE)){};

    void update(CMS* cms);
    float timeLimit;
    int motType;
};

class ZUC_SET_SIM_ENABLE : public RCS_CMD_MSG
{
public:
    ZUC_SET_SIM_ENABLE() : RCS_CMD_MSG(ZUC_SET_SIM_ENABLE_TYPE, sizeof(ZUC_SET_SIM_ENABLE)){};

    void update(CMS* cms);
    int simEnable;  // 0 for disable, none-zero for enable
};

// declarations for ZUC_TRAJ classes

class ZUC_TRAJ_DELAY : public RCS_CMD_MSG
{
public:
    ZUC_TRAJ_DELAY() : RCS_CMD_MSG(ZUC_TRAJ_DELAY_TYPE, sizeof(ZUC_TRAJ_DELAY)) { line_num = -1; };

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int line_num;
    double delay;  // delay in seconds
};

class ZUC_SET_MUTI_TOOL_OFFSET : public RCS_CMD_MSG
{
public:
    ZUC_SET_MUTI_TOOL_OFFSET() : RCS_CMD_MSG(ZUC_SET_MUTI_TOOL_OFFSET_TYPE, sizeof(ZUC_SET_MUTI_TOOL_OFFSET)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    ZucPose robotToolOffset;
    int id;
    char name[LINELEN];
    unsigned char method;
};

class ZUC_SET_MUTI_USER_OFFSET : public RCS_CMD_MSG
{
public:
    ZUC_SET_MUTI_USER_OFFSET() : RCS_CMD_MSG(ZUC_SET_MUTI_USER_OFFSET_TYPE, sizeof(ZUC_SET_MUTI_USER_OFFSET)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    ZucPose robotUserOffset;
    int id;
    char name[LINELEN];
    unsigned char method;
};

class ZUC_TRAJ_SET_PAYLOAD : public RCS_CMD_MSG
{
public:
    ZUC_TRAJ_SET_PAYLOAD() : RCS_CMD_MSG(ZUC_TRAJ_SET_PAYLOAD_TYPE, sizeof(ZUC_TRAJ_SET_PAYLOAD)){};

    void update(CMS* cms);
    int id;
    Payload payload;
};

class ZUC_SET_SAFE_ZONE : public RCS_CMD_MSG
{
public:
    ZUC_SET_SAFE_ZONE() : RCS_CMD_MSG(ZUC_SET_SAFE_ZONE_TYPE, sizeof(ZUC_SET_SAFE_ZONE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int openEnable;
    int autoEnable;
    int count;
    int coordinateSystemTransformation;
    SafeZone zone;
};

// zuc_MOTION is aggregate of all ZUC motion-related status classes

// ZUC_MOTION command base class
class ZUC_MOTION_CMD_MSG : public RCS_CMD_MSG
{
public:
    ZUC_MOTION_CMD_MSG(NMLTYPE t, size_t s) : RCS_CMD_MSG(t, s){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_SERVO_UPGRADE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_SERVO_UPGRADE() : ZUC_MOTION_CMD_MSG(ZUC_SERVO_UPGRADE_TYPE, sizeof(ZUC_SERVO_UPGRADE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_MOTION_INIT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_INIT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_INIT_TYPE, sizeof(ZUC_MOTION_INIT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_MOTION_HALT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_HALT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_HALT_TYPE, sizeof(ZUC_MOTION_HALT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_MOTION_SET_AOUT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_AOUT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_AOUT_TYPE, sizeof(ZUC_MOTION_SET_AOUT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    unsigned char type;   // io type, 0-->basic io, 1-->tool io
    unsigned char index;  // which to set
    double start;         // value at start
    double end;           // value at end
    unsigned char now;    // wether command is imediate or synched with motion
};

//
class ZUC_MOTION_SET_DOUT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_DOUT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_DOUT_TYPE, sizeof(ZUC_MOTION_SET_DOUT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    unsigned char type;   // io type: 0-->basic io, 1-->tio; 2-->modbus io; 3-->profinet io
    int index;            // which to set	// which to set
    unsigned char start;  // binary value at start
    unsigned char end;    // binary value at end
    unsigned char now;    // wether command is imediate or synched with motion
};

class ZUC_MOTION_PERCENTAGE_MODE_LEVEL_VALUE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_PERCENTAGE_MODE_LEVEL_VALUE()
        : ZUC_MOTION_CMD_MSG(ZUC_MOTION_PERCENTAGE_MODE_LEVEL_VALUE_TYPE, sizeof(ZUC_MOTION_PERCENTAGE_MODE_LEVEL_VALUE)){};

    void update(CMS* cms);
    double percentage_mode_level1_val;
    double percentage_mode_level2_val;
};

class ZUC_MOTION_SET_FREE_BUTTON_OPT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_FREE_BUTTON_OPT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_FREE_BUTTON_OPT_TYPE, sizeof(ZUC_MOTION_SET_FREE_BUTTON_OPT)){};

    void update(CMS* cms);
    bool freeButton;
};

class ZUC_MOTION_SET_FREE_PROG_BUTTON_OPT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_FREE_PROG_BUTTON_OPT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_FREE_PROG_BUTTON_OPT_TYPE, sizeof(ZUC_MOTION_SET_FREE_PROG_BUTTON_OPT)){};

    void update(CMS* cms);
    int freeButton;
    int progButton;
};

class ZUC_MOTION_SET_POINT_BUTTON_OPT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_POINT_BUTTON_OPT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_POINT_BUTTON_OPT_TYPE, sizeof(ZUC_MOTION_SET_POINT_BUTTON_OPT)){};

    void update(CMS* cms);
    bool pointButton;
};

class ZUC_MOTION_SET_BR_STRT_VOLTAGE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_BR_STRT_VOLTAGE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_BR_STRT_VOLTAGE_TYPE, sizeof(ZUC_MOTION_SET_BR_STRT_VOLTAGE)) {}

    void update(CMS* cms);
    int starting_voltage;
};

class ZUC_MOTION_SETUP_IO_CHANNEL : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SETUP_IO_CHANNEL() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SETUP_IO_CHANNEL_TYPE, sizeof(ZUC_MOTION_SETUP_IO_CHANNEL)) {}

    void update(CMS* cms);
    int channel_type;
    int channel_index;
    int channel_setting;  // for digital channel, 0 for di and 1 for do
};

class ZUC_SHUT_DOWN : public RCS_CMD_MSG
{
public:
    ZUC_SHUT_DOWN() : RCS_CMD_MSG(ZUC_SHUT_DOWN_TYPE, sizeof(ZUC_SHUT_DOWN)){};
    void update(CMS* cms);
};

class ZUC_MBTIO_ADD_SIGNAL : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MBTIO_ADD_SIGNAL() : ZUC_MOTION_CMD_MSG(ZUC_MBTIO_ADD_SIGNAL_TYPE, sizeof(ZUC_MBTIO_ADD_SIGNAL)) {}
    void update(CMS* cms);
    char sigName[128];
    unsigned int chnId;
    unsigned int type;
    unsigned int addr;
};

class ZUC_MBTIO_DEL_SIGNAL : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MBTIO_DEL_SIGNAL() : ZUC_MOTION_CMD_MSG(ZUC_MBTIO_DEL_SIGNAL_TYPE, sizeof(ZUC_MBTIO_DEL_SIGNAL)) {}
    void update(CMS* cms);
    char sigName[128];
};

class ZUC_MBTIO_UPDATE_SIGNAL : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MBTIO_UPDATE_SIGNAL() : ZUC_MOTION_CMD_MSG(ZUC_MBTIO_UPDATE_SIGNAL_TYPE, sizeof(ZUC_MBTIO_UPDATE_SIGNAL)) {}
    void update(CMS* cms);
    char sigName[128];
    float freq;
};

class ZUC_MBTIO_SEND_COMMAND : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MBTIO_SEND_COMMAND() : ZUC_MOTION_CMD_MSG(ZUC_MBTIO_SEND_COMMAND_TYPE, sizeof(ZUC_MBTIO_SEND_COMMAND)) {}
    void update(CMS* cms);
    int chnId;
    int length;
    unsigned char command[32];  // do not contain the CRC, but include the slave id
};

class ZUC_MOTION_SET_CAPTURE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_CAPTURE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_CAPTURE_TYPE, sizeof(ZUC_MOTION_SET_CAPTURE)) {}

    void update(CMS* cms);
    int captureId;
    int stateToCapt;
    IOTrigger trigger;
};

class ZUC_MOTION_CLEAR_CAPTURE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_CLEAR_CAPTURE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_CLEAR_CAPTURE_TYPE, sizeof(ZUC_MOTION_CLEAR_CAPTURE)) {}

    void update(CMS* cms);
    int captureId;
};

class Robot_SET_FULL_DH_FLAG : public ZUC_MOTION_CMD_MSG
{
public:
    Robot_SET_FULL_DH_FLAG() : ZUC_MOTION_CMD_MSG(Robot_SET_FULL_DH_FLAG_TYPE, sizeof(Robot_SET_FULL_DH_FLAG)){};
    void update(CMS* cms);
    int full_dh_flag;  // 0: 臂角固定且根据当前机器人关节角状态计算 1: 臂角固定且根据输入arm_angle计算 2: 臂型角随动，根据当前臂型角为起点
};
class ZUC_MOTION_ONE_KEY_OP : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_ONE_KEY_OP() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_ONE_KEY_OP_TYPE, sizeof(ZUC_MOTION_ONE_KEY_OP)) {}

    void update(CMS* cms);
    // int auto_op_setting;//0--off one key operation 1--auto enabled 2--auto running program 3-- auto enabled and running program
    int onekeyenable;  // 1--auto enabled  0-- off
    int autoprogram;   // 1--auto running program 0--off
};

class ZUC_MOTION_ADAPTIVE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_ADAPTIVE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_ADAPTIVE_TYPE, sizeof(ZUC_MOTION_ADAPTIVE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    unsigned char status;  // status=0 stop; status=1 start.
};

class ZUC_MOTION_EXIT_PROTECT : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_EXIT_PROTECT() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_EXIT_PROTECT_TYPE, sizeof(ZUC_MOTION_EXIT_PROTECT)) {}

    void update(CMS* cms);
    int protect_type;
};

class ZUC_MOTION_PERCENTAGE_MODE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_PERCENTAGE_MODE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_PERCENTAGE_MODE_TYPE, sizeof(ZUC_MOTION_PERCENTAGE_MODE)) {}
    void update(CMS* cms);
    int percentage_level;
};

class ZUC_MOTION_REDUCE_MODE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_REDUCE_MODE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_REDUCE_MODE_TYPE, sizeof(ZUC_MOTION_REDUCE_MODE)) {}
    void update(CMS* cms);
    int reduce_mode;
};

class ZUC_MOTION_KINE_INVERSE : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_KINE_INVERSE() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_KINE_INVERSE_TYPE, sizeof(ZUC_MOTION_KINE_INVERSE)) {}
    // For internal NML/CMS use only.
    void update(CMS* cms);
    int robindex;
    ZucPose tarPose;
    double currJoint[ZUCMOT_MAX_JOINTS];
};

class ZUC_MOTION_KINE_FORWARD : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_KINE_FORWARD() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_KINE_FORWARD_TYPE, sizeof(ZUC_MOTION_KINE_FORWARD)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int robindex;
    double joints[ZUCMOT_MAX_JOINTS];
};

class ZUC_MOTION_SET_FUNCDI : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_FUNCDI() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_FUNCDI_TYPE, sizeof(ZUC_MOTION_SET_FUNCDI)){};

    void update(CMS* cms);
    FuncIOMap funcIOMap;
};

class ZUC_MOTION_SET_FUNCDO : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_FUNCDO() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_FUNCDO_TYPE, sizeof(ZUC_MOTION_SET_FUNCDO)){};

    void update(CMS* cms);
    FuncIOMap funcIOMap;
};

class ZUC_MOTION_SET_SAFETY_FUNCDI : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_SAFETY_FUNCDI() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_SAFETY_FUNCDI_TYPE, sizeof(ZUC_MOTION_SET_SAFETY_FUNCDI)) {}

    void update(CMS* cms);
    SafetyFuncDIMap sFuncDISettings;
};

class ZUC_MOTION_SET_SAFETY_FUNCDO : public ZUC_MOTION_CMD_MSG
{
public:
    ZUC_MOTION_SET_SAFETY_FUNCDO() : ZUC_MOTION_CMD_MSG(ZUC_MOTION_SET_SAFETY_FUNCDO_TYPE, sizeof(ZUC_MOTION_SET_SAFETY_FUNCDO)) {}

    void update(CMS* cms);
    SafetyFuncDOMap sFuncDOSettings;
};

class ZUC_MONITOR_STAT : public RCS_STAT_MSG
{
public:
    ZUC_MONITOR_STAT() : RCS_STAT_MSG(ZUC_MONITOR_STAT_TYPE, sizeof(ZUC_MONITOR_STAT))
    {
        scb_hw_version = 0;
        scb_sw_version = 0;
        memset(scb_ver_str, 0, sizeof(scb_ver_str));
        cabTemperature = 0.0;
        robotAveragePower = 0.0;
        robotAverageCurrent = 0.0;
        robotVoltage = 0.0;
        cabinetID = 0;
        currRunTime = 0;
        accuRunTime = 0;
        commState = 0;
        for (int i = 0; i < ZUCMOT_MAX_JOINTS; i++)
        {
            jointMonitorData[i].instCurrent = 0.0;
            jointMonitorData[i].instVoltage = 0.0;
            jointMonitorData[i].instTemperature = 0.0;
            jointMonitorData[i].insAveragePower = 0.0;
            jointMonitorData[i].currentFluctuation = 0.0;
            jointMonitorData[i].sumRunningCircles = 0.0;
            jointMonitorData[i].sumRunningTime = 0.0;
            jointMonitorData[i].curRunningCircles = 0.0;
            jointMonitorData[i].curRunningTime = 0.0;
            jointMonitorData[i].jointTorque = 0.0;
            jointMonitorData[i].jointTorqueCmd = 0.0;
            jointMonitorData[i].positionDiff = 0.0;
            jointMonitorData[i].dualEncoderDiff = 0.0;
            jointMonitorData[i].jointDcVol = 0.0;
            jointMonitorData[i].reserved = 0.0;
        }
    };

    void update(CMS* cms);
    int scb_hw_version;
    int scb_sw_version;
    char scb_ver_str[128];

    float cabTemperature;
    float robotAveragePower;
    float robotAverageCurrent;
    float robotVoltage;
    unsigned int cabinetID;
    unsigned int currRunTime;
    unsigned int accuRunTime;
    unsigned char commState;
    JointMonitorData jointMonitorData[ZUCMOT_MAX_JOINTS];
};

// declarations for ZUC_TASK classes

// ZUC_TASK command base class
class ZUC_TASK_CMD_MSG : public RCS_CMD_MSG
{
public:
    ZUC_TASK_CMD_MSG(NMLTYPE t, size_t s) : RCS_CMD_MSG(t, s){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_INIT : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_INIT() : ZUC_TASK_CMD_MSG(ZUC_TASK_INIT_TYPE, sizeof(ZUC_TASK_INIT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_HALT : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_HALT() : ZUC_TASK_CMD_MSG(ZUC_TASK_HALT_TYPE, sizeof(ZUC_TASK_HALT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_ABORT : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_ABORT() : ZUC_TASK_CMD_MSG(ZUC_TASK_ABORT_TYPE, sizeof(ZUC_TASK_ABORT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_SET_MODE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SET_MODE() : ZUC_TASK_CMD_MSG(ZUC_TASK_SET_MODE_TYPE, sizeof(ZUC_TASK_SET_MODE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    enum ZUC_TASK_MODE_ENUM mode;
};

class ZUC_TASK_SET_OPERATION_MODE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SET_OPERATION_MODE() : ZUC_TASK_CMD_MSG(ZUC_TASK_SET_OPERATION_MODE_TYPE, sizeof(ZUC_TASK_SET_OPERATION_MODE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    enum ZUC_TASK_OPERATION_MODE_ENUM opmode;
};

class ZUC_TASK_SET_STATE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SET_STATE() : ZUC_TASK_CMD_MSG(ZUC_TASK_SET_STATE_TYPE, sizeof(ZUC_TASK_SET_STATE)) { robid = -1; };

    // For internal NML/CMS use only.
    void update(CMS* cms);

    enum ZUC_TASK_STATE_ENUM state;
    int robid;
};

class ZUC_TASK_SET_AUTOWORK : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SET_AUTOWORK() : ZUC_TASK_CMD_MSG(ZUC_TASK_SET_AUTOWORK_TYPE, sizeof(ZUC_TASK_SET_AUTOWORK)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int enable;
    char filename[LINELEN];
};

class ZUC_TASK_SET_SCRIPT_BACKUP : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SET_SCRIPT_BACKUP() : ZUC_TASK_CMD_MSG(ZUC_TASK_SET_SCRIPT_BACKUP_TYPE, sizeof(ZUC_TASK_SET_SCRIPT_BACKUP)){};

    void update(CMS* cms);
    int enable;
    float interval;
};

class ZUC_TASK_PLAN_OPEN : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_OPEN() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_OPEN_TYPE, sizeof(ZUC_TASK_PLAN_OPEN)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    char file[LINELEN];
};

class ZUC_TASK_PLAN_RUN : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_RUN() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_RUN_TYPE, sizeof(ZUC_TASK_PLAN_RUN)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    int line;  // line to run from; 0 or 1 means from start,
               // negative means run through to verify
};

class ZUC_TASK_PLAN_READ : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_READ() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_READ_TYPE, sizeof(ZUC_TASK_PLAN_READ)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_EXECUTE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_EXECUTE() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_EXECUTE_TYPE, sizeof(ZUC_TASK_PLAN_EXECUTE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    char command[LINELEN];
};

class ZUC_TASK_PLAN_PAUSE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_PAUSE() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_PAUSE_TYPE, sizeof(ZUC_TASK_PLAN_PAUSE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_STEP : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_STEP() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_STEP_TYPE, sizeof(ZUC_TASK_PLAN_STEP)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_RESUME : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_RESUME() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_RESUME_TYPE, sizeof(ZUC_TASK_PLAN_RESUME)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_END : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_END() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_END_TYPE, sizeof(ZUC_TASK_PLAN_END)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_CLOSE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_CLOSE() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_CLOSE_TYPE, sizeof(ZUC_TASK_PLAN_CLOSE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_INIT : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_INIT() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_INIT_TYPE, sizeof(ZUC_TASK_PLAN_INIT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_SYNCH : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_SYNCH() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_SYNCH_TYPE, sizeof(ZUC_TASK_PLAN_SYNCH)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_PLAN_SET_OPTIONAL_STOP : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_SET_OPTIONAL_STOP() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_SET_OPTIONAL_STOP_TYPE, sizeof(ZUC_TASK_PLAN_SET_OPTIONAL_STOP)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    bool state;  //state == ON, optional stop is on (e.g. we stop on any stops)
};

class ZUC_TASK_PLAN_SET_BLOCK_DELETE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_SET_BLOCK_DELETE() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_SET_BLOCK_DELETE_TYPE, sizeof(ZUC_TASK_PLAN_SET_BLOCK_DELETE)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);

    bool state;  //state == ON, block delete is on, we ignore lines starting with "/"
};

class ZUC_TASK_PLAN_OPTIONAL_STOP : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_PLAN_OPTIONAL_STOP() : ZUC_TASK_CMD_MSG(ZUC_TASK_PLAN_OPTIONAL_STOP_TYPE, sizeof(ZUC_TASK_PLAN_OPTIONAL_STOP)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_TASK_CALC_TCP : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_CALC_TCP() : ZUC_TASK_CMD_MSG(ZUC_TASK_CALC_TCP_TYPE, sizeof(ZUC_TASK_CALC_TCP)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int methodtype;
    unsigned char id;
    unsigned char saveType;
    unsigned char statusFlag;
    double jntpoint1[ZUCMOT_MAX_JOINTS];
    double jntpoint2[ZUCMOT_MAX_JOINTS];
    double jntpoint3[ZUCMOT_MAX_JOINTS];
    double jntpoint4[ZUCMOT_MAX_JOINTS];
    double jntpoint5[ZUCMOT_MAX_JOINTS];
    double jntpoint6[ZUCMOT_MAX_JOINTS];
};

class ZUC_TASK_CALC_SAFEATT : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_CALC_SAFEATT() : ZUC_TASK_CMD_MSG(ZUC_TASK_CALC_SAFEATT_TYPE, sizeof(ZUC_TASK_CALC_SAFEATT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    ZucPose cartpos1;
    ZucPose cartpos2;
    ZucPose cartpos3;
    double tilt;
    double pan;
    int tipChoice;
};

class ZUC_TASK_CALC_USER : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_CALC_USER() : ZUC_TASK_CMD_MSG(ZUC_TASK_CALC_USER_TYPE, sizeof(ZUC_TASK_CALC_USER)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    unsigned char id;
    unsigned char saveType;
    unsigned char statusFlag;
    double jntpoint1[ZUCMOT_MAX_JOINTS];
    double jntpoint2[ZUCMOT_MAX_JOINTS];
    double jntpoint3[ZUCMOT_MAX_JOINTS];
};

class ZUC_TASK_SET_USER_DEFINED_VARIABLE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SET_USER_DEFINED_VARIABLE() : ZUC_TASK_CMD_MSG(ZUC_TASK_USER_DEFINED_VARIABLE_TYPE, sizeof(ZUC_TASK_SET_USER_DEFINED_VARIABLE)) {}
    // For internal NML/CMS use only.
    void update(CMS* cms);
    int id;
    double value;
};

class ZUC_TASK_SETUP_TIO_RS485_MODE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SETUP_TIO_RS485_MODE() : ZUC_TASK_CMD_MSG(ZUC_TASK_SETUP_TIO_RS485_MODE_TYPE, sizeof(ZUC_TASK_SETUP_TIO_RS485_MODE)) {}
    // For internal NML/CMS use only.
    void update(CMS* cms);
    int id;    // 0: chn1, 1: chn2
    int mode;  // 0: Modbus RTU, 1: RS485, 2: torque sensor
};

class ZUC_TASK_SETUP_TIO_RS485_COMM : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SETUP_TIO_RS485_COMM() : ZUC_TASK_CMD_MSG(ZUC_TASK_SETUP_TIO_RS485_COMM_TYPE, sizeof(ZUC_TASK_SETUP_TIO_RS485_COMM)) {}
    // For internal NML/CMS use only.
    void update(CMS* cms);
    int id;              // 0: chn1, 1: chn2
    ModRtuComm rtuComm;  // for RS485, slave id doesn't work
};

class ZUC_TASK_SETUP_TIO_PIN_MODE : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SETUP_TIO_PIN_MODE() : ZUC_TASK_CMD_MSG(ZUC_TASK_SETUP_TIO_PIN_MODE_TYPE, sizeof(ZUC_TASK_SETUP_TIO_PIN_MODE)) {}
    // For internal NML/CMS use only.
    void update(CMS* cms);
    int type;  // pin type: 0-din, 1-dout, 2-ain
    int mode;  // configs for all pins of specified type
};

class ZUC_TASK_SETUP_TIO_VOUT_ENA : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SETUP_TIO_VOUT_ENA() : ZUC_TASK_CMD_MSG(ZUC_TASK_SETUP_TIO_VOUT_ENA_TYPE, sizeof(ZUC_TASK_SETUP_TIO_VOUT_ENA)) {}
    void update(CMS* cms);
    int enable;  // configs for all pins of specified type
};

class ZUC_TASK_SETUP_TIO_VOUT_VOL : public ZUC_TASK_CMD_MSG
{
public:
    ZUC_TASK_SETUP_TIO_VOUT_VOL() : ZUC_TASK_CMD_MSG(ZUC_TASK_SETUP_TIO_VOUT_VOL_TYPE, sizeof(ZUC_TASK_SETUP_TIO_VOUT_VOL)) {}
    void update(CMS* cms);
    int voltage;  // 0 for 24V, 1 for 12V, others: 24V
};

// ZUC_TASK status base class
class ZUC_TASK_STAT_MSG : public RCS_STAT_MSG
{
public:
    ZUC_TASK_STAT_MSG(NMLTYPE t, size_t s) : RCS_STAT_MSG(t, s) { heartbeat = 0; };

    // For internal NML/CMS use only.
    void update(CMS* cms);
    uint32_t heartbeat;
};

class ZUC_TASK_STAT : public ZUC_TASK_STAT_MSG
{
public:
    ZUC_TASK_STAT();

    // For internal NML/CMS use only.
    void update(CMS* cms);
    enum ZUC_TASK_MODE_ENUM mode;           // ZUC_TASK_MODE_MANUAL, etc.
    enum ZUC_TASK_STATE_ENUM state;         // ZUC_TASK_STATE_POWERED_OFF, etc.
    enum ZUC_TASK_EXEC_ENUM execState;      // ZUC_DONE,WAITING_FOR_MOTION, etc.
    enum ZUC_TASK_INTERP_ENUM interpState;  // ZUC_IDLE,READING,PAUSED,WAITING
    int callLevel;                          // current subroutine level - 0 if not in a subroutine, > 0 otherwise
    int motionLine;                         // line motion is executing-- may lag
    int currentLine;                        // line currently issued
    int readLine;                           // line interpreter has read to
    int sleepLine;                          // sleep line actually executing
    int executingLine;                      // the executing line of the program, executingLine = max(motionLine, sleepLine)
    bool optional_stop_state;               // state of optional stop (== ON means we stop on M1)
    bool block_delete_state;                // state of block delete (== ON means we ignore lines starting with "/")
    bool input_timeout;                     // has a timeout happened on digital input
    char file[LINELEN];                     // current file
    char file_auto_mode[LINELEN];           // file opened on auto-mode
    char file_manu_mode[LINELEN];           // file opened on manu-mode
    char command[LINELEN];
    ZucPose robotToolOffset;  // robot tool offset
    ZucPose robotUserOffset;  // robot user offset

    CANON_UNITS programUnits;  // CANON_UNITS_INCHES,MM,CM

    int interpreter_errcode;  // return value from rs274ngc function
    // (only useful for new interpreter.)
    int task_paused;        // non-zero means task is paused
    double delayLeft;       // delay time left of G4, M66..
    int queuedMDIcommands;  // current length of MDI input queue
    PmRpy base_offset;      // in degree
    AutoWorkConfig autoWork;
    ScriptsBackupSetting backupSetting;
    int clsnDetectMethod;
    int clsnReactTypeWhenProgRun;
    double clsnReactReboundAngle;
    JointTraj payloadIdentifyTraj[4];
    int errAddLine;
    struct CallStack
    {
        char file[LINELEN];
        int executingLine;
    } callStack[4];
    int progInExec;
};

// ZUC_AUX command base class
class ZUC_AUX_CMD_MSG : public RCS_CMD_MSG
{
public:
    ZUC_AUX_CMD_MSG(NMLTYPE t, size_t s) : RCS_CMD_MSG(t, s){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_AUX_INPUT_WAIT : public ZUC_AUX_CMD_MSG
{
public:
    ZUC_AUX_INPUT_WAIT() : ZUC_AUX_CMD_MSG(ZUC_AUX_INPUT_WAIT_TYPE, sizeof(ZUC_AUX_INPUT_WAIT)) { line_num = -1; };

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int line_num;

    int index;       // input channel to wait for
    int input_type;  // 0=ANALOG 1=DIGITAL or 2=TOOL_DI
    int wait_type;   // 0 - immediate, 1- rise, 2 - fall, 3 - be high, 4 - be low
    double timeout;  // timeout for waiting
};

// ZUC command base class
class ZUC_CMD_MSG : public RCS_CMD_MSG
{
public:
    ZUC_CMD_MSG(NMLTYPE t, size_t s) : RCS_CMD_MSG(t, s){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_INIT : public ZUC_CMD_MSG
{
public:
    ZUC_INIT() : ZUC_CMD_MSG(ZUC_INIT_TYPE, sizeof(ZUC_INIT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_HALT : public ZUC_CMD_MSG
{
public:
    ZUC_HALT() : ZUC_CMD_MSG(ZUC_HALT_TYPE, sizeof(ZUC_HALT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_ABORT : public ZUC_CMD_MSG
{
public:
    ZUC_ABORT() : ZUC_CMD_MSG(ZUC_ABORT_TYPE, sizeof(ZUC_ABORT)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

/**
 added by alex.li for set the checking can connection paramter to motion
 */
class ZUC_SET_CHECK_CAN_CONNECTION : public ZUC_CMD_MSG
{
public:
    ZUC_SET_CHECK_CAN_CONNECTION() : ZUC_CMD_MSG(ZUC_SET_CHECK_CAN_CONNECTION_TYPE, sizeof(ZUC_SET_CHECK_CAN_CONNECTION)){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
    int check;
};

// ZUC status base class

class ZUC_STAT_MSG : public RCS_STAT_MSG
{
public:
    ZUC_STAT_MSG(NMLTYPE t, size_t s) : RCS_STAT_MSG(t, s){};

    // For internal NML/CMS use only.
    void update(CMS* cms);
};

class ZUC_STEP_STATUS : public RCS_CMD_MSG
{
public:
    ZUC_STEP_STATUS() : RCS_CMD_MSG(ZUC_STEP_STATUS_TYPE, sizeof(ZUC_STEP_STATUS)){};

    void update(CMS* cms);
    int isSteping;          // 0: step end, 1: steping
    int programRunTrigger;  // 0: no run program; 1: run program;
    int stepEnd;            // 0: no end; 1: end
};

class ZUC_SET_GRPC_ERRCODE : public RCS_CMD_MSG
{
public:
    ZUC_SET_GRPC_ERRCODE() : RCS_CMD_MSG(ZUC_SET_GRPC_ERRCODE_TYPE, sizeof(ZUC_SET_GRPC_ERRCODE)) {}

    void update(CMS* cms);
    int grpc_errtype;
    int grpc_errcode;
    char grpc_errmsg[LINELEN];
    int repeatflag = 0xff;  //bits 1:GRPC repeat? 2: TCP repeat? 3:reserve
    char saveFlag = 0;      // 0:不记录到errorlog， 1: 写入errorlog
};

class ZUC_COLLECT_DIAG_DATA : public RCS_CMD_MSG
{
public:
    ZUC_COLLECT_DIAG_DATA() : RCS_CMD_MSG(ZUC_COLLECT_DIAG_DATA_TYPE, sizeof(ZUC_COLLECT_DIAG_DATA)) {}

    void update(CMS* cms);
    int isStart = 0;  //0-stop 1-start
};

class ZUC_STAT : public ZUC_STAT_MSG
{
public:
    ZUC_STAT();
    void update(CMS* cms);
    ZUC_MOTION_ONE_KEY_OP autoopsetting;
    ZUC_TASK_STAT task;
    ZUC_MOTION_STAT motion;
    ZUC_MOTION_STAT ext_motion[2];
    ZUC_TIO_STAT tio[3];

    ZUC_MONITOR_STAT monitor;
    ZUC_IO_STAT io;
    ZUC_SAFE_STAT safe;

    char robotName[LINELEN];
    int debug;                  // copy of ZUC_DEBUG global
    int operation_mode;         // can switch between auto and manual
    int operation_mode_option;  // operation mode option, 1 refers to enable operation mode

    int mbSlaveCommType;
    CommInfo mbSlaveCommInfo;
    int isSteppingMode;
    int steppingState;
    int steppingWait;
    int cab_type;

    int func_licence;
    // int auto_op_setting;
    ZUC_ROBOT_SAFETY robotSafe[6];  // 0:custom limit, 1:old_cuntom limit, 2:no limit, 3:loose limit, 4:medium limit,5: strict limit
    double robotSafety[19];
    ZUC_JOINT_SAFETY jointLimit[ZUCMOT_ROBOT_MAX_JOINTS * 2];  // 0-5: custom limit   6-11: default limit
    ZUC_STEP_STATUS stepStatus;
    ZUC_SET_NET_EXCEPTION_HANDLE netExceptionHandle;
    char sub_thread_state[MAX_SUB_THREAD][LINELEN] = {0};
    int grpc_errtype;
    int grpc_errcode;
    int repeatflag = 0xff;  //8bits 1:tcp repeat? 2: grpc repeat? 3:reserve
    char grpc_errmsg[LINELEN];
    int appConnectionStatus;
    int currSimMode;
    int currSimRobot;
    int initSimMode;
    ZUC_REDUCE_SAFETY reduceSafe;
    char isDiagCollecting;  //是否处于诊断状态

    int scb_br_start_vol;
    int scb_stick_locked;

    int servo_upGrade_percentage_total;
    int servo_upGrade_percentage_axis;

    int usrOpeErrCode;  // 0: success, -1: failure
    ZucPose toolOffset[16];
    ZucPose userOffset[18];
    Payload payload[16];

    int curCabVoltage;
};

/*
 Declarations of ZUC status class implementations, for major subsystems.
 These are defined in the appropriate main() files, and referenced
 by code in other files to get ZUC status.
 */

#endif
